import { def } from './utils.js'

/* 获取数组中的原型 */
const arrayProperty = Array.prototype;
console.log(arrayProperty);
/* 以Array.prototype为原型创建arrayMethods对象 */
/* 其实就是克隆了一个Array对象 */
export const arrayMethods = Object.create(arrayProperty);

console.log(arrayMethods);
const methodsNeedChange = [
  'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'
];

/* 其实这里做的是，给arrayMethods对象新增这7个方法，用户访问数组中的这7个方法的时候，会优先使用我们定义的这7个方法
而不会使用数组的中那7个方法。
原因 原型链---->
其实就是重写了数组中的那7个方法
*/
methodsNeedChange.forEach(methodName => {
  // 备份原来的方法
  const original = arrayProperty[methodName];
  // 定义新的方法
  /* 给对象定义一个不可枚举的函数 */
  def(arrayMethods, methodName, function () {
    const args = [...arguments];
    /* 恢复原来的功能（原有数组的中的方法功能不变） */
    /* 执行original方法 */
    const result = original.apply(this, args);
    /* 把这个数组身上的__ob__取出来 */
    const ob = this.__ob__;
    /* 三个特殊的方法，特殊处理的目的是，这些数据也需要是可侦测的 */
    let inserted = [];
    switch (methodName) {
      case 'push':
      case 'unshift':
        inserted = args;
        break;
      case 'splice':
        inserted = [...args].slice(2);
        break;
    }

    if (inserted) {
      /* 需要是插入的数据也是响应式的 */
      ob.observeArray(inserted);
      /* 此时为什么只需要取出当前调用对象的ob实例，而不是新的Observes对象的实例？
        因为当前对象已经是可侦测的了
      */
    }
    /* 在这里可以干其他操作 */

    return result;
  }, false)
})
console.log(arrayMethods);